/*
Contains various structs and includes
*/

#ifndef UNI_INCLUDES_H
#define UNI_INCLUDES_H

#include <string>
#include <vector>

#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "SDL/SDL_opengl.h"
#include "GL/glu.h"

static struct Color
{
    float red, green, blue, alpha;
    Color()
    {
        red = green = blue = alpha = 1.0f;
    }
    Color(float r = 1.0f, float g = 1.0f, float b = 1.0f, float a = 1.0f)
    {
        red = r; green = g; blue = b; alpha = a;
    }

}NoColor(0.0f, 0.0f, 0.0f, 0.0f),
White(1.0f, 1.0f, 1.0f, 1.0f),
Red(1.0f, 0.0f, 0.0f, 1.0f),
Gray(0.5f, 0.5f, 0.5f, 1.0f),
Black(0.0f, 0.0f, 0.0f, 1.0f);
// Ehem: http://www.greyorgray.com/

// Callback to class methods with a (void*) parameter.
class Callback
{
     public:
          virtual void operator()(void* ref)=0;  // Call using operator
          virtual void call(void* ref)=0;        // Call using function
};
template <class TClass> class SpecificCallback : public Callback
{
    private:
        void (TClass::*fpt)(void*);                                 // Pointer to member function
        TClass* pt2Object;                                          // Pointer to object
    public:
        SpecificCallback(TClass* _pt2Object, void(TClass::*_fpt)(void*))
        {
            pt2Object = _pt2Object;
            fpt = _fpt;
        }
        virtual void operator()(void* ref)
        {
            (*pt2Object.*fpt)(ref);
        }                                 // Execute member function
        virtual void call(void* ref)
        {
            (*pt2Object.*fpt)(ref);
        }                                 // Execute member function
};

// Callback method structure for console methods.
// This allows us to tie a name to a class method.
class ConsoleMethod
{
    public:
        std::string methodName;
        virtual void operator()(std::string m, std::vector<std::string> args) = 0;   // Call operator
        virtual void call(std::string m, std::vector<std::string> args) = 0;
};
template <class TClass> class SpecificConsoleMethod : public ConsoleMethod
{
    private:
        void (TClass::*fpt)(std::string, std::vector<std::string>);
        TClass* pt2Object;
    public:
        SpecificConsoleMethod(TClass* _pt2Object,
                              void(TClass::*_fpt)(std::string,std::vector<std::string>),
                              std::string _methodName)
        {
            pt2Object = _pt2Object;
            fpt = _fpt;
            methodName = _methodName;
        }
        virtual void operator()(std::string m, std::vector<std::string> args)
        {
            (*pt2Object.*fpt)(methodName, args);
        }
        virtual void call(std::string m, std::vector<std::string> args)
        {
            (*pt2Object.*fpt)(methodName, args);
        }
};

struct RectType
{
    float x;
    float y;
    float width;
    float height;
    RectType()
    {
        x = 0.0f;
        y = 0.0f;
        width = 0.0f;
        height = 0.0f;
    }
    // Using an initialisation list for the constructor
    RectType(float x, float y, float width, float height) : x(x), y(y), width(width), height(height) {}

    static bool contains(RectType* a, float x, float y)
    {
        if(a != 0)
        {
            if(x >= a->x && x <= a->x+a->width && y >= a->y && y <= a->y+a->height)
                return true;
        }
        return false;
    }
};


#endif
